package com.xdj.iot.util.excelUtils;

import com.xdj.iot.util.excelUtils.processor.ExcelProcessor;
import com.xdj.iot.util.excelUtils.processor.processorImpl.StandardExcelProcessor;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Font;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * created by chongyahhh
 * 2020/2/21
 */

public class ExcelAssistBean {
    private String sheetName;
    private List<String> orderedTitles;
    private List<?> data;
    private Class targetClass;
    private List<Field> orderedFields;
    private List<HSSFCellStyle> titleStyle;
    private List<HSSFCellStyle> contentStyle;
    private HSSFWorkbook hssfWorkbook;
    private ExcelProcessor excelProcessor = new StandardExcelProcessor();
    private boolean customMode = false;

    public ExcelAssistBean() {
    }

    public ExcelAssistBean(HSSFWorkbook hssfWorkbook,String sheetName, List<?> data, Class targetClass) {
        this.hssfWorkbook = hssfWorkbook;
        this.sheetName = sheetName;
        this.data = data;
        this.targetClass = targetClass;
        initExcelAssistBean();
    }

    public ExcelAssistBean(HSSFWorkbook hssfWorkbook,String sheetName, List<?> data, Class targetClass, ExcelProcessor excelProcessor) {
        this.hssfWorkbook = hssfWorkbook;
        this.sheetName = sheetName;
        this.data = data;
        this.targetClass = targetClass;
        this.excelProcessor = excelProcessor;
        initExcelAssistBean();
    }

    public ExcelAssistBean(HSSFWorkbook hssfWorkbook,String sheetName, List<?> data, Class targetClass, boolean customMode) {
        this.hssfWorkbook = hssfWorkbook;
        this.sheetName = sheetName;
        this.data = data;
        this.targetClass = targetClass;
        this.customMode = customMode;
        initExcelAssistBean();
    }

    public ExcelAssistBean(HSSFWorkbook hssfWorkbook,String sheetName, List<?> data, Class targetClass, ExcelProcessor excelProcessor, boolean customMode) {
        this.hssfWorkbook = hssfWorkbook;
        this.sheetName = sheetName;
        this.data = data;
        this.targetClass = targetClass;
        this.excelProcessor = excelProcessor;
        this.customMode = customMode;
        initExcelAssistBean();
    }

    private void initExcelAssistBean(){
        Field[] fields = targetClass.getDeclaredFields();
        orderedFields = new ArrayList<>();
        for(Field temp : fields){
            if(temp.getAnnotation(ExcelColumn.class) != null){
                orderedFields.add(temp);
            }
        }
        orderedFields.sort(Comparator.comparingInt(field -> field.getAnnotation(ExcelColumn.class).order()));
        orderedTitles = new ArrayList<>();
        for(Field temp : orderedFields){
            orderedTitles.add(temp.getAnnotation(ExcelColumn.class).description());
        }
        //如果开启自定义模式
        if(customMode){
            titleStyle = new ArrayList<>();
            contentStyle = new ArrayList<>();
            HSSFCellStyle currentCellStyle;
            Font font;
            for(Field temp : orderedFields){
                currentCellStyle = hssfWorkbook.createCellStyle();
                font = hssfWorkbook.createFont();
                font.setFontHeightInPoints(temp.getAnnotation(ExcelColumn.class).titleFontSize());
                font.setBoldweight(temp.getAnnotation(ExcelColumn.class).titleFontWeight());
                font.setColor(temp.getAnnotation(ExcelColumn.class).titleFontColor());
                currentCellStyle.setLocked(false);  // 表头均不能修改
                currentCellStyle.setFont(font);
                titleStyle.add(currentCellStyle);
                currentCellStyle = hssfWorkbook.createCellStyle();
                font = hssfWorkbook.createFont();
                font.setFontHeightInPoints(temp.getAnnotation(ExcelColumn.class).contentFontSize());
                font.setBoldweight(temp.getAnnotation(ExcelColumn.class).contentFontWeight());
                font.setColor(temp.getAnnotation(ExcelColumn.class).contentFontColor());
                currentCellStyle.setLocked(temp.getAnnotation(ExcelColumn.class).columnLocked());
                currentCellStyle.setFont(font);
                contentStyle.add(currentCellStyle);
            }
        }
    }

    public void titleCellStyleInvoke(HSSFRow row){
        HSSFCell titleCell;
        for(int titleIndex = 0;titleIndex < orderedTitles.size();titleIndex++){
            titleCell = row.createCell(titleIndex);
            titleCell.setCellStyle(titleStyle.get(titleIndex));
            titleCell.setCellValue(orderedTitles.get(titleIndex));
        }
    }

    public void contentCellStyleInvoke(HSSFSheet hssfSheet, int firstRowNum)throws Exception{
        HSSFRow currentRow;
        for(int rowIndex = 0;rowIndex < data.size();rowIndex++){
            currentRow = hssfSheet.createRow(rowIndex + firstRowNum + 1);
            HSSFCell currentCell;
            Object obj = data.get(rowIndex);
            for(int cellIndex = 0;cellIndex < orderedFields.size();cellIndex++){
                currentCell = currentRow.createCell(cellIndex);
                currentCell.setCellStyle(contentStyle.get(cellIndex));
                if(!orderedFields.get(cellIndex).isAccessible()){
                    orderedFields.get(cellIndex).setAccessible(true);
                    if(orderedFields.get(cellIndex).get(obj) != null){
                        currentCell.setCellValue(orderedFields.get(cellIndex).get(obj).toString());
                    }
                    orderedFields.get(cellIndex).setAccessible(false);
                } else {
                    if(orderedFields.get(cellIndex).get(obj) != null){
                        currentCell.setCellValue(orderedFields.get(cellIndex).get(obj).toString());
                    }
                }
            }
        }
    }

    public String getSheetName() {
        return sheetName;
    }

    public void setSheetName(String sheetName) {
        this.sheetName = sheetName;
    }

    public List<String> getOrderedTitles() {
        return orderedTitles;
    }

    public void setOrderedTitles(List<String> orderedTitles) {
        this.orderedTitles = orderedTitles;
    }

    public List<?> getData() {
        return data;
    }

    public void setData(List<?> data) {
        this.data = data;
    }

    public Class getTargetClass() {
        return targetClass;
    }

    public void setTargetClass(Class targetClass) {
        this.targetClass = targetClass;
    }

    public List<Field> getOrderedFields() {
        return orderedFields;
    }

    public void setOrderedFields(List<Field> orderedFields) {
        this.orderedFields = orderedFields;
    }

    public ExcelProcessor getExcelProcessor() {
        return excelProcessor;
    }

    public void setExcelProcessor(ExcelProcessor excelProcessor) {
        this.excelProcessor = excelProcessor;
    }

    public boolean isCustomMode() {
        return customMode;
    }

    public void setCustomMode(boolean customMode) {
        this.customMode = customMode;
    }

    public List<HSSFCellStyle> getTitleStyle() {
        return titleStyle;
    }

    public void setTitleStyle(List<HSSFCellStyle> titleStyle) {
        this.titleStyle = titleStyle;
    }

    public List<HSSFCellStyle> getContentStyle() {
        return contentStyle;
    }

    public void setContentStyle(List<HSSFCellStyle> contentStyle) {
        this.contentStyle = contentStyle;
    }

    public HSSFWorkbook getHssfWorkbook() {
        return hssfWorkbook;
    }

    public void setHssfWorkbook(HSSFWorkbook hssfWorkbook) {
        this.hssfWorkbook = hssfWorkbook;
    }
}
